import datetime
import os.path
import sys
import pandas as pd
# Import the backtrader platform
import backtrader as bt
# ---------------------------------------------------------------
#                    添加指示器
# ----——————————-------------------------------------------------

# 创建一个策略
class TestStrategy(bt.Strategy):
    params=(('maperiod',15),)
    #-------------------------------------------------------------------------
    def log(self, txt, dt=None):
        ''' 这个策略的日志'''
        dt = dt or self.datas[0].datetime.date(0)
        print('{}, {}'.format(dt.isoformat(), txt))

    def __init__(self):
        # 以收盘线为参考
        self.dataclose = self.datas[0].close
        # 跟踪下单
        self.order=None
        self.buyprice=None
        self.buycomm=None

        self.sma=bt.indicators.MovingAverageSimple(self.data[0],period=self.params.maperiod)
    
    def notify_order(self,order):
        if order.status in [order.Submitted,order.Accepted]:
            # Buy/Sell order submitted/accepted to/by broker - Nothing to do
            return
        
        # 检测下单是否完成
        # 注意：如果不够钱，broker会拒绝下单
        if order.status in [order.Completed]:
            if order.isbuy():
                self.log('买！执行,价格{},{},{}'.format(order.executed.price
                                                ,order.executed.value
                                                ,order.executed.comm))
                self.buyprice=order.executed.price
                self.buycomm=order.executed.comm
            
            else:  # 卖
                self.log('卖！执行, {},{},{}'.format(order.executed.price
                                                ,order.executed.value
                                                ,order.executed.comm))

            self.bar_executed = len(self)

        elif order.status in [order.Canceled, order.Margin, order.Rejected]:
            self.log('Order Canceled/Margin/Rejected')

        # Write down: no pending order
        self.order = None

    #-----------------------------------------------------------------------
    def notify_trade(self,trade):
        if not trade.isclosed:
            return
        
        self.log('经营利润，毛利{},NET {}'.format(trade.pnl,trade.pnlcomm))

    #-----------------------------------------------------------------------
    def next(self):
        self.log('Close, {}'.format(self.dataclose[0]))

        # 如果order已经发送，就不要发第二次了
        if self.order:
            return
        
        # 检测我们是否在市场中
        if not self.position:
            # 如果不在市场中，我们就要买买买
            if self.dataclose[0]>self.sma[0]:
                self.log("买进{}".format(self.dataclose[0]))
                self.buy()
        #如果已经在市场中，我们可能要卖一点
        else:
            if len(self) <self.sma[0]:
                # 卖卖卖
                self.log('创建卖单, {}'.format(self.dataclose[0]))

                # Keep track of the created order to avoid a 2nd order
                self.order = self.sell()

            

if __name__ == '__main__':
    cerebro = bt.Cerebro()

    # Add a strategy
    cerebro.addstrategy(TestStrategy)

    path='C:\Users\Administrator\Downloads/backtrader-master\datas/2006-min-005.txt'
    dataframe = pd.read_csv(path, index_col=0, parse_dates=True)

    dataframe['openinterest'] = 0
    data = bt.feeds.PandasData(dataname=dataframe)


    # Add the Data Feed to Cerebro
    cerebro.adddata(data)

    # Set our desired cash start
    cerebro.broker.setcash(100000.0)

    cerebro.addsizer(bt.sizers.fixedsize,stake=10)

    cerebro.broker.setcommission(commission=0.0)     #手续费

    # Print out the starting conditions
    print('投资组合启动:{}'.format(cerebro.broker.getvalue()))

    # Run over everything
    cerebro.run()

    # Print out the final result
    print('投资组合关闭:{}'.format(cerebro.broker.getvalue()))